package org.springblade.modules.admin.service.feishu.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.similarities.Lambda;
import org.springblade.common.enums.FeiShuDocumentEnum;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tenant.mp.TenantEntity;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.MaintainPlanContentUserDTO;
import org.springblade.modules.admin.dto.feishu.FeiShuBatchDTO;
import org.springblade.modules.admin.dto.feishu.FeiShuFieldsDTO;
import org.springblade.modules.admin.dto.plan.PlanSearchDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.service.feishu.IFeiShuDocumentService;
import org.springblade.modules.admin.service.feishu.ILarkMaintenanceService;
import org.springblade.modules.admin.vo.feishu.LarkRepairVO;
import org.springblade.modules.admin.vo.plan.PlanListVo;
import org.springblade.modules.admin.vo.plan.PlanSignStatusVo;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.service.IDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Sharry
 * @since 2024-05-17
 */
@Service
@Slf4j
public class LarkMaintenanceServiceImpl implements ILarkMaintenanceService {

	@Autowired
	private IFeiShuDocumentService feiShuDocumentService;

	@Autowired
	@Lazy
	private IMaintainPlanContentService maintainPlanContentService;

	@Autowired
	private IPlanCheckHistoryScoreService planCheckHistoryScoreService;

	@Autowired
	private IMaintainPlanContentExtService maintainPlanContentExtService;

	@Autowired
	private IDictService dictService;

	@Autowired
	private ElevatorService elevatorService;

	@Autowired
	private IMaintainPlanContentUserService maintainPlanContentUserService;

	@Autowired
	private BladeRedis bladeRedis;

	private static final String LARK_SCORE_LOCK_KEY = "LARK_SCORE_SEND_";

	@Override
	@Async
	public void sendPlanScoreLarkMessage(Long planId) {
		String activeProfile = System.getProperty("spring.profiles.active");

			// 1. 数据准备，appToken, tableId, 同步对象
			// 复用分页逻辑获取列表，再从中获取单个planId对应的记录，并组装成同步对象
			PlanSearchDTO planSearchDTO = new PlanSearchDTO();
			planSearchDTO.setPlanId(planId);
			List<PlanListVo> planListVos = maintainPlanContentService.planListNewLark(planSearchDTO);
			if(Func.isNotEmpty(planListVos)){
				String appToken;
				String tableId;
				if ("prod".equals(activeProfile)) {
					appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA.getAppToken();
					tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA.getTableId();
				}else{
					appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA_COPY.getAppToken();
					tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA_COPY.getTableId();
				}
				// 2. 数据处理、数据封装
				FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
				List<FeiShuFieldsDTO> records = new ArrayList<>();
				for (PlanListVo planListVo : planListVos) {
					FeiShuFieldsDTO element = new FeiShuFieldsDTO();
					Map<String, Object> elementMap = new HashMap<>(24);
					elementMap.put("梯无忧_保养工单任务ID", String.valueOf(planListVo.getPlanId()));
					elementMap.put("梯无忧_电梯快速识别码", planListVo.getElevatorNum());
					String templateNames = planListVo.getTemplateNames();
					// 1747154112313532417-天雄测试模板,1763081415090966530-天雄保养模板,3-半年保养,4-年度保养
					// 只获取 - 与 , 之间的字符串
					if(!Func.isNull(templateNames)){
						String[] templateNamesArray = templateNames.split(",");
						List<String> templateNameList = new ArrayList<>();
						for (String templateName : templateNamesArray) {
							String[] templateNameArray = templateName.split("-");
							if (templateNameArray.length > 1) {
								templateNameList.add(templateNameArray[1]);
							}
						}
						elementMap.put("任务描述", templateNameList.toArray(new String[0]));
					}
					elementMap.put("项目名称", planListVo.getBuildingName());
					elementMap.put("电梯位置", planListVo.getElevatorAddress());
					if(!Func.isNull(planListVo.getRealNames())){
						String[] realNamesArray = planListVo.getRealNames().split(",");
						elementMap.put("计划执行人", realNamesArray);
					}
					if(!Func.isNull(planListVo.getPlanDate())){
						String planDateString = planListVo.getPlanDate();
						// yyyy-MM-dd 的字符串格式化成 Date
						Date planDate = DateUtil.parse(planDateString, "yyyy-MM-dd");
						elementMap.put("当前计划时间", planDate.getTime());
					}
					// 实际执行人
					List<PlanSignStatusVo> planSignStatusList = planListVo.getPlanSignStatusList();
					List<String> actualExecuteList = new ArrayList<>();
					if(!Func.isEmpty(planSignStatusList)){
						planSignStatusList.stream().map(PlanSignStatusVo::getUserName).forEach(actualExecuteList::add);
						elementMap.put("实际执行人", actualExecuteList.toArray(new String[0]));
					}
					if(!Func.isNull(planListVo.getPlanStartTime())){
						String planStartTimeString = planListVo.getPlanStartTime();
						Date planStartTime = DateUtil.parse(planStartTimeString, "yyyy-MM-dd HH:mm:ss");
						elementMap.put("开始时间", planStartTime.getTime());
					}
					if(!Func.isNull(planListVo.getPlanEndTime())){
						String planEndTimeString = planListVo.getPlanEndTime();
						Date planEndTime = DateUtil.parse(planEndTimeString, "yyyy-MM-dd HH:mm:ss");
						elementMap.put("完成时间", planEndTime.getTime());
					}
					// 有效判定
					if(!Func.isNull(planListVo.getScoreType())){
						if (planListVo.getScoreType() == 1) {
							elementMap.put("有效判定", "有效工单");
						} else if (planListVo.getScoreType() == 2) {
							elementMap.put("有效判定", "无效工单");
						} else if (planListVo.getScoreType() == 3) {
							elementMap.put("有效判定", "无法判断");
						}
					}
					// 工单评分
					if(!Func.isNull(planListVo.getScore())){
						elementMap.put("工单评分", String.valueOf(planListVo.getScore()));
					}
					// 评分时间
					MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(
						new LambdaQueryWrapper<MaintainPlanContentExt>()
							.eq(MaintainPlanContentExt::getPlanId, planListVo.getPlanId())
							.eq(BaseEntity::getIsDeleted, 0)
					);
					// 评分人
					List<PlanCheckHistoryScore> scoreUsers = planCheckHistoryScoreService.list(new LambdaQueryWrapper<PlanCheckHistoryScore>()
						.eq(PlanCheckHistoryScore::getPlanId, planListVo.getPlanId())
						.eq(BaseEntity::getIsDeleted, 0)
					);
					if(!Func.isEmpty(scoreUsers)){
						List<String> collect = scoreUsers.stream().map(PlanCheckHistoryScore::getScoreUserName).collect(Collectors.toList());
						if(!Func.isEmpty(collect)){
							elementMap.put("评分人", collect.toArray(new String[0]));
						}
					}else{
						String scoreUserName = maintainPlanContentExt.getScoreUserName();
						if(!Func.isNull(scoreUserName)){
							List<String> scoreUserNameList = new ArrayList<>();
							scoreUserNameList.add(scoreUserName);
							elementMap.put("评分人", scoreUserNameList.toArray(new String[0]));
						}
					}
					if(!Func.isNull(maintainPlanContentExt)){
						Date scoreTime = maintainPlanContentExt.getScoreDate();
						if(!Func.isNull(scoreTime)){
							elementMap.put("评分时间", scoreTime.getTime());
						}
						// 工单总分备注
						if(!Func.isNull(maintainPlanContentExt.getScoreRemark())){
							elementMap.put("工单总分备注", maintainPlanContentExt.getScoreRemark().split(","));
						}
						// 评分状态
						Integer scoreStatus = maintainPlanContentExt.getScoreStatus();
						if(!Func.isNull(scoreStatus)){
							elementMap.put("评分状态", new Integer(1).equals(scoreStatus) ? "已评分" : "未评分");
						}
						// 工单整体评价标签
						if(!Func.isNull(maintainPlanContentExt.getScoreFutilityDesc())){
							String[] split = maintainPlanContentExt.getScoreFutilityDesc().split(",");
							elementMap.put("工单整体评价标签",split);
						}
					}
					// 任务状态
					MaintainPlanContent currentPlan = maintainPlanContentService.getById(planListVo.getPlanId());
					Integer status = currentPlan.getStatus();
					if(!Func.isNull(status)) {
						String taskName = TaskStatusEnum.getTaskName(1, status);
						elementMap.put("任务状态", taskName);
					}
					element.setFields(elementMap);
					records.add(element);
				}
				batchDTO.setRecords(records);
				// 3. 执行并发送消息
				// 2024-06-12 新增 redis 锁，防止重复发送
				String key = LARK_SCORE_LOCK_KEY + planId;
				// 如果不存在key
				if (!bladeRedis.exists(key)){
					bladeRedis.setEx(key, UUID.randomUUID().toString(), Duration.ofSeconds(20L));
					String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"梯无忧_保养工单任务ID");
					String finalResult = "工单评分触发" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
					feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
					// 执行完毕后，移除key
					bladeRedis.del(key);
				}else{
					// 等待直到key失效
					try {
						log.info("key:{} 未失效，正在等待20秒后重试", key);
						Thread.sleep(20000);
						String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"梯无忧_保养工单任务ID");
						String finalResult = "工单评分触发" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
						feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
				}

			}
	}

	/**
	 * 当前方法仅适用592800租户
	 * @param planId 维修工单id
	 */
	@Override
	@Async
	public void sendRepairLarkMessageCopy(Long planId) {
		// 1. 数据准备,  主表appToken, tableId； 两张关联表的appToken，tableId 同步对象
		String appToken = FeiShuDocumentEnum.ELEVATOR_QUEUE_COPY.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_QUEUE_COPY.getTableId();
		String elevatorTableAppToken = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO_COPY.getAppToken();
		String elevatorTableId = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO_COPY.getTableId();
		String userTableAppToken = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO_COPY.getAppToken();
		String userTableId = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO_COPY.getTableId();
		List<LarkRepairVO> targetList = maintainPlanContentService.getLarkRepairVOListByPlanId(planId);
		if(Func.isEmpty(targetList)){
			return;
		}
		// 数据处理
		targetList.forEach(t -> {
			// 15、60 天重复故障次数
			// 15 天时间区间
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, -15);
			Date fifteenDaysBeginTime = calendar.getTime();
			Date fifteenDaysEndTime = new Date();
			// 60 天时间区间
			calendar.add(Calendar.DAY_OF_MONTH, -60);
			Date sixtyDaysBeginTime = calendar.getTime();
			Date sixtyDaysEndTime = new Date();
			// 15 天重复故障次数
			int fifteenDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), fifteenDaysBeginTime, fifteenDaysEndTime
			);
			// 60 天重复故障次数
			int sixtyDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), sixtyDaysBeginTime, sixtyDaysEndTime
			);
			t.setFifteenDayRepeatTimes(fifteenDaysRepeatCount);
			t.setSixtyDayRepeatTimes(sixtyDaysRepeatCount);
			t.setIsRepeat(fifteenDaysRepeatCount > 1 || sixtyDaysRepeatCount > 2);
			// 工单完成时间、工单是否已完成
			MaintainPlanContent currentPlan = maintainPlanContentService.getById(t.getPlanId());
			if (!Func.isNull(currentPlan)){
				int statusValue = TaskStatusEnum.WX_SIGN_FINISH.getStatus();
				if(new Integer(statusValue).equals(currentPlan.getStatus())){
					t.setFinishTime(currentPlan.getUpdateTime());
					t.setIsFinish(true);
				}
			}
			// 执行人列表
			Long currentPlanId = currentPlan.getId();
			//  2024-06-12 修复改为：包括已删除的执行人列表，取时间最小值
			List<MaintainPlanContentUser> executorList = maintainPlanContentUserService.listAllContentUsersByPlanId(currentPlanId);
			if(!Func.isEmpty(executorList)){
				t.setDispatchTime(executorList.get(0).getCreateTime());
				t.setExecutorIds(
					executorList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList())
				);
			}
			if(!Func.isEmpty(executorList)){
				t.setDispatchTime(executorList.get(0).getCreateTime());
			}
			List<MaintainPlanContentUser> actuallyExecutorList = maintainPlanContentUserService.list(
				new LambdaQueryWrapper<MaintainPlanContentUser>()
					.eq(MaintainPlanContentUser::getPlanId, currentPlanId)
					.eq(BaseEntity::getIsDeleted, 0)
			);
			if(!Func.isEmpty(actuallyExecutorList)){
				t.setExecutorIds(
					actuallyExecutorList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList())
				);
			}
			// 工单作业时长分钟
			MaintainPlanContentExt workMinutes = maintainPlanContentExtService.getOne(new LambdaQueryWrapper<MaintainPlanContentExt>()
				.eq(MaintainPlanContentExt::getPlanId, currentPlanId)
				.eq(BaseEntity::getIsDeleted, 0)
			);
			if(!Func.isNull(workMinutes)){
				t.setWorkTime(workMinutes.getWorkMinute());
			}
		});
		// 2. 电梯信息表关联处理
		Map<String, String> elevatorMap = new HashMap<>(100);
		List<JSONObject> elevatorJsonObjects = feiShuDocumentService.commandQueryBatch(elevatorTableAppToken, elevatorTableId, null);
		if(Func.isNotEmpty(elevatorJsonObjects)){
			elevatorJsonObjects.forEach(
				e -> {
					JSONObject elevatorFields = e.getJSONObject("fields");
					String elevatorNum = elevatorFields.getString("电梯编号");
					if(!Func.isNull(elevatorNum)){
						elevatorMap.put(elevatorNum, e.getString("record_id"));
					}
				}
			);
		}
		// 3. 人员信息表关联处理
		Map<String, String> userMap = new HashMap<>(100);
		List<JSONObject> userJsonObjects = feiShuDocumentService.commandQueryBatch(userTableAppToken, userTableId, null);
		if(Func.isNotEmpty(userJsonObjects)){
			userJsonObjects.forEach(
				u -> {
					JSONObject userFields = u.getJSONObject("fields");
					String userId = userFields.getString("人员ID");
					if(!Func.isNull(userId)){
						userMap.put(userId, u.getString("record_id"));
					}
				}
			);
		}
		// 4. 数据封装，先插入没有关联的记录，再插入有关联的记录
		FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
		List<FeiShuFieldsDTO> records = new ArrayList<>();
		for (LarkRepairVO larkRepairVO : targetList) {
			FeiShuFieldsDTO element = new FeiShuFieldsDTO();
			Map<String, Object> elementMap = new HashMap<>(24);
			elementMap.put("工单编号", String.valueOf(larkRepairVO.getPlanId()));
			if(elevatorMap.containsKey(String.valueOf(larkRepairVO.getElevatorId()))){
				List<String> relationIds = new ArrayList<>();
				relationIds.add(elevatorMap.get(String.valueOf(larkRepairVO.getElevatorId())));
				elementMap.put("电梯编号", relationIds.toArray(new String[0]));
			}
			if(Func.isNotEmpty(larkRepairVO.getExecutorIds())){
				List<String> executorIds = new ArrayList<>();
				larkRepairVO.getExecutorIds().forEach(
					e -> {
						if(userMap.containsKey(String.valueOf(e))){
							executorIds.add(userMap.get(String.valueOf(e)));
						}
					});
				if(!Func.isEmpty(executorIds)){
					elementMap.put("人员ID", executorIds.toArray(new String[0]));
				}
			}
			elementMap.put("电梯位置（梯号）", larkRepairVO.getElevatorAddress());
			elementMap.put("报障人", larkRepairVO.getReporterName());
			elementMap.put("报障人联系方式",larkRepairVO.getReporterPhone());
			Integer planFromType = larkRepairVO.getPlanFromType();
			// 任务来源: 1: 物业端, 2: 微信, 3: 服务电话, 4: 系统派单, 5: 维保端，6: 游客, 7: web, 8: 梯联网
			// Switch 语句
			if(!Func.isNull(planFromType)){
				String planFromDesc = "";
				switch (planFromType) {
					case 1:
						planFromDesc = "物业端";
						break;
					case 2:
						planFromDesc = "微信";
						break;
					case 3:
						planFromDesc = "服务电话";
						break;
					case 4:
						planFromDesc = "系统派单";
						break;
					case 5:
						planFromDesc = "维保端";
						break;
					case 6:
						planFromDesc = "游客";
						break;
					case 7:
						planFromDesc = "web";
						break;
					case 8:
						planFromDesc = "梯联网";
						break;
					default:
						planFromDesc = "该工单梯无忧未记录来源";
						break;
				}
				elementMap.put("故障来源", planFromDesc);
			}
			if(!Func.isNull(larkRepairVO.getPlanDesc())){
				List<String> planDescList = Arrays.asList(larkRepairVO.getPlanDesc().split(","));
				List<String> planDescListNew = new ArrayList<>();
				planDescList.forEach(
					p ->{
						Dict dictValue = dictService.getOne(Wrappers.<Dict>lambdaQuery()
							.eq(Dict::getCode, "fault_problem")
							.eq(Dict::getDictKey, p)
							.eq(Dict::getIsDeleted,0)
						);
						if(!Func.isNull(dictValue)){
							planDescListNew.add(dictValue.getDictValue());
						}
					}
				);
				elementMap.put("故障现象",planDescListNew.toArray(new String[0]));
			}
			elementMap.put("故障描述",larkRepairVO.getRepairDesc());
			elementMap.put("电梯状态",new Integer(1).equals(larkRepairVO.getIsStop()) ? "正常" : "停梯");
			Elevator currentElevator = elevatorService.getById(larkRepairVO.getElevatorId());
			Long currentBuildingId = currentElevator.getBuildingId();
			int count = elevatorService.count(new LambdaQueryWrapper<Elevator>()
				.eq(Elevator::getBuildingId, currentBuildingId)
				.eq(TenantEntity::getTenantId,592800)
				.eq(Elevator::getIsDeleted, 0)
			);
			elementMap.put("是否多台梯",count);
			elementMap.put("15天重复故障次数",larkRepairVO.getFifteenDayRepeatTimes());
			elementMap.put("60天重复故障次数",larkRepairVO.getSixtyDayRepeatTimes());
			elementMap.put("是否重复故障",larkRepairVO.getIsRepeat() ? "是" : "否");
			elementMap.put("项目名称",larkRepairVO.getBuildingName());
			elementMap.put("是否驻点",new Integer(1).equals(larkRepairVO.getStagnationPoint()) ? "不限" : "驻点");
			elementMap.put("项目类型", larkRepairVO.getBuildingType());
			if(!Func.isNull(larkRepairVO.getPlanCreateTime())){
				elementMap.put("工单创建时间", larkRepairVO.getPlanCreateTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getFinishTime())){
				elementMap.put("工单完成时间", larkRepairVO.getFinishTime().getTime());
				elementMap.put("工单是否已完成", "是");
			}
			else {
				elementMap.put("工单是否已完成", "否");
			}
			elementMap.put("创建人", larkRepairVO.getCreateUserName());
			if(!Func.isNull(larkRepairVO.getDispatchTime())){
				elementMap.put("调度时间", larkRepairVO.getDispatchTime().getTime());
			}
			elementMap.put("工单类型","维修");
			// 签到时间
			if(!Func.isNull(larkRepairVO.getSignTime())){
				elementMap.put("工单签到时间", larkRepairVO.getSignTime().getTime());
			}
//			if(!Func.isNull(larkRepairVO.getSignOutTime())){
//				elementMap.put("工单签退时间", larkRepairVO.getSignOutTime().getTime());
//			}
//			if(!Func.isNull(larkRepairVO.getWorkTime())){
//				elementMap.put("工单作业耗时", new Integer(larkRepairVO.getWorkTime()));
//			}
			element.setFields(elementMap);
			records.add(element);
		}
		batchDTO.setRecords(records);
		// 5. 执行并发送消息
		// 2024-06-12 新增 redis 锁，防止重复发送
		String key = LARK_SCORE_LOCK_KEY + planId;
		// 如果不存在key
		if (!bladeRedis.exists(key)){
			bladeRedis.setEx(key, UUID.randomUUID().toString(), Duration.ofSeconds(20L));
			String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"工单编号");
			String finalResult = "维修触发记录" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
			feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
			// 执行完毕后，移除key
			bladeRedis.del(key);
		}else{
			// 等待直到key失效
			try {
				log.info("key:{} 未失效，正在等待20秒后继续进行", key);
				Thread.sleep(20000);
				String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"工单编号");
				String finalResult = "维修触发记录" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
				feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
		}
	}

	/**
	 * 当前方法仅适用592800租户
	 * @param planId 维修工单id
	 */
	@Override
	@Async
	public void sendRepairLarkMessage(Long planId) {
		// 1. 数据准备,  主表appToken, tableId； 两张关联表的appToken，tableId 同步对象
		String appToken = FeiShuDocumentEnum.ELEVATOR_QUEUE.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_QUEUE.getTableId();
		String elevatorTableAppToken = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO.getAppToken();
		String elevatorTableId = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO.getTableId();
		String userTableAppToken = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO.getAppToken();
		String userTableId = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO.getTableId();
		List<LarkRepairVO> targetList = maintainPlanContentService.getLarkRepairVOListByPlanId(planId);
		if(Func.isEmpty(targetList)){
			return;
		}
		// 数据处理
		targetList.forEach(t -> {
			// 15、60 天重复故障次数
			// 15 天时间区间
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, -15);
			Date fifteenDaysBeginTime = calendar.getTime();
			Date fifteenDaysEndTime = new Date();
			// 60 天时间区间
			calendar.add(Calendar.DAY_OF_MONTH, -60);
			Date sixtyDaysBeginTime = calendar.getTime();
			Date sixtyDaysEndTime = new Date();
			// 15 天重复故障次数
			int fifteenDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), fifteenDaysBeginTime, fifteenDaysEndTime
			);
			// 60 天重复故障次数
			int sixtyDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), sixtyDaysBeginTime, sixtyDaysEndTime
			);
			t.setFifteenDayRepeatTimes(fifteenDaysRepeatCount);
			t.setSixtyDayRepeatTimes(sixtyDaysRepeatCount);
			t.setIsRepeat(fifteenDaysRepeatCount > 1 || sixtyDaysRepeatCount > 2);
			// 工单完成时间、工单是否已完成
			MaintainPlanContent currentPlan = maintainPlanContentService.getById(t.getPlanId());
			if (!Func.isNull(currentPlan)){
				int statusValue = TaskStatusEnum.WX_SIGN_FINISH.getStatus();
				if(new Integer(statusValue).equals(currentPlan.getStatus())){
					t.setFinishTime(currentPlan.getUpdateTime());
					t.setIsFinish(true);
				}
			}
			// 执行人列表
			Long currentPlanId = currentPlan.getId();
			//  2024-06-12 修复改为：包括已删除的执行人列表，取时间最小值
			List<MaintainPlanContentUser> executorList = maintainPlanContentUserService.listAllContentUsersByPlanId(currentPlanId);
			if(!Func.isEmpty(executorList)){
				t.setDispatchTime(executorList.get(0).getCreateTime());
			}
			List<MaintainPlanContentUser> actuallyExecutorList = maintainPlanContentUserService.list(
				new LambdaQueryWrapper<MaintainPlanContentUser>()
					.eq(MaintainPlanContentUser::getPlanId, currentPlanId)
					.eq(BaseEntity::getIsDeleted, 0)
			);
			if(!Func.isEmpty(actuallyExecutorList)){
				t.setExecutorIds(
					actuallyExecutorList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList())
				);
			}
			// 工单作业时长分钟
			MaintainPlanContentExt workMinutes = maintainPlanContentExtService.getOne(new LambdaQueryWrapper<MaintainPlanContentExt>()
				.eq(MaintainPlanContentExt::getPlanId, currentPlanId)
				.eq(BaseEntity::getIsDeleted, 0)
			);
			if(!Func.isNull(workMinutes)){
				t.setWorkTime(workMinutes.getWorkMinute());
			}
		});
		// 2. 电梯信息表关联处理
		Map<String, String> elevatorMap = new HashMap<>(100);
		List<JSONObject> elevatorJsonObjects = feiShuDocumentService.commandQueryBatch(elevatorTableAppToken, elevatorTableId, null);
		if(Func.isNotEmpty(elevatorJsonObjects)){
			elevatorJsonObjects.forEach(
				e -> {
					JSONObject elevatorFields = e.getJSONObject("fields");
					String elevatorNum = elevatorFields.getString("电梯编号");
					if(!Func.isNull(elevatorNum)){
						elevatorMap.put(elevatorNum, e.getString("record_id"));
					}
				}
			);
		}
		// 3. 人员信息表关联处理
		Map<String, String> userMap = new HashMap<>(100);
		List<JSONObject> userJsonObjects = feiShuDocumentService.commandQueryBatch(userTableAppToken, userTableId, null);
		if(Func.isNotEmpty(userJsonObjects)){
			userJsonObjects.forEach(
				u -> {
					JSONObject userFields = u.getJSONObject("fields");
					String userId = userFields.getString("人员ID");
					if(!Func.isNull(userId)){
						userMap.put(userId, u.getString("record_id"));
					}
				}
			);
		}
		// 4. 数据封装，先插入没有关联的记录，再插入有关联的记录
		FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
		List<FeiShuFieldsDTO> records = new ArrayList<>();
		for (LarkRepairVO larkRepairVO : targetList) {
			FeiShuFieldsDTO element = new FeiShuFieldsDTO();
			Map<String, Object> elementMap = new HashMap<>(24);
			elementMap.put("工单编号", String.valueOf(larkRepairVO.getPlanId()));
			if(elevatorMap.containsKey(String.valueOf(larkRepairVO.getElevatorId()))){
				List<String> relationIds = new ArrayList<>();
				relationIds.add(elevatorMap.get(String.valueOf(larkRepairVO.getElevatorId())));
				elementMap.put("电梯编号", relationIds.toArray(new String[0]));
			}
			if(Func.isNotEmpty(larkRepairVO.getExecutorIds())){
				List<String> executorIds = new ArrayList<>();
				larkRepairVO.getExecutorIds().forEach(
					e -> {
						if(userMap.containsKey(String.valueOf(e))){
							executorIds.add(userMap.get(String.valueOf(e)));
						}
					});
				if(!Func.isEmpty(executorIds)){
					elementMap.put("人员ID", executorIds.toArray(new String[0]));
				}
			}
			elementMap.put("电梯位置（梯号）", larkRepairVO.getElevatorAddress());
			elementMap.put("报障人", larkRepairVO.getReporterName());
			elementMap.put("报障人联系方式",larkRepairVO.getReporterPhone());
			Integer planFromType = larkRepairVO.getPlanFromType();
			// 任务来源: 1: 物业端, 2: 微信, 3: 服务电话, 4: 系统派单, 5: 维保端，6: 游客, 7: web, 8: 梯联网
			// Switch 语句
			if(!Func.isNull(planFromType)){
				String planFromDesc = "";
				switch (planFromType) {
					case 1:
						planFromDesc = "物业端";
						break;
					case 2:
						planFromDesc = "微信";
						break;
					case 3:
						planFromDesc = "服务电话";
						break;
					case 4:
						planFromDesc = "系统派单";
						break;
					case 5:
						planFromDesc = "维保端";
						break;
					case 6:
						planFromDesc = "游客";
						break;
					case 7:
						planFromDesc = "web";
						break;
					case 8:
						planFromDesc = "梯联网";
						break;
					default:
						planFromDesc = "该工单梯无忧未记录来源";
						break;
				}
				elementMap.put("故障来源", planFromDesc);
			}
			if(!Func.isNull(larkRepairVO.getPlanDesc())){
				List<String> planDescList = Arrays.asList(larkRepairVO.getPlanDesc().split(","));
				List<String> planDescListNew = new ArrayList<>();
				planDescList.forEach(
					p ->{
						Dict dictValue = dictService.getOne(Wrappers.<Dict>lambdaQuery()
							.eq(Dict::getCode, "fault_problem")
							.eq(Dict::getDictKey, p)
							.eq(Dict::getIsDeleted,0)
						);
						if(!Func.isNull(dictValue)){
							planDescListNew.add(dictValue.getDictValue());
						}
					}
				);
				elementMap.put("故障现象",planDescListNew.toArray(new String[0]));
			}
			elementMap.put("故障描述",larkRepairVO.getRepairDesc());
			elementMap.put("电梯状态",new Integer(1).equals(larkRepairVO.getIsStop()) ? "正常" : "停梯");
			Elevator currentElevator = elevatorService.getById(larkRepairVO.getElevatorId());
			Long currentBuildingId = currentElevator.getBuildingId();
			int count = elevatorService.count(new LambdaQueryWrapper<Elevator>()
				.eq(Elevator::getBuildingId, currentBuildingId)
				.eq(TenantEntity::getTenantId,592800)
				.eq(Elevator::getIsDeleted, 0)
			);
			elementMap.put("是否多台梯",count);
			elementMap.put("15天重复故障次数",larkRepairVO.getFifteenDayRepeatTimes());
			elementMap.put("60天重复故障次数",larkRepairVO.getSixtyDayRepeatTimes());
			elementMap.put("是否重复故障",larkRepairVO.getIsRepeat() ? "是" : "否");
			elementMap.put("项目名称",larkRepairVO.getBuildingName());
			elementMap.put("是否驻点",new Integer(1).equals(larkRepairVO.getStagnationPoint()) ? "不限" : "驻点");
			elementMap.put("项目类型", larkRepairVO.getBuildingType());
			if(!Func.isNull(larkRepairVO.getPlanCreateTime())){
				elementMap.put("工单创建时间", larkRepairVO.getPlanCreateTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getFinishTime())){
				elementMap.put("工单完成时间", larkRepairVO.getFinishTime().getTime());
				elementMap.put("工单是否已完成", "是");
			}
			else {
				elementMap.put("工单是否已完成", "否");
			}
			elementMap.put("创建人", larkRepairVO.getCreateUserName());
			if(!Func.isNull(larkRepairVO.getDispatchTime())){
				elementMap.put("调度时间", larkRepairVO.getDispatchTime().getTime());
			}
			elementMap.put("工单类型","维修");
			// 签到时间
			if(!Func.isNull(larkRepairVO.getSignTime())){
				elementMap.put("工单签到时间", larkRepairVO.getSignTime().getTime());
			}
//			if(!Func.isNull(larkRepairVO.getSignOutTime())){
//				elementMap.put("工单签退时间", larkRepairVO.getSignOutTime().getTime());
//			}
//			if(!Func.isNull(larkRepairVO.getWorkTime())){
//				elementMap.put("工单作业耗时", new Integer(larkRepairVO.getWorkTime()));
//			}
			element.setFields(elementMap);
			records.add(element);
		}
		batchDTO.setRecords(records);
		// 5. 执行并发送消息
		// 2024-06-12 新增 redis 锁，防止重复发送
		String key = LARK_SCORE_LOCK_KEY + planId;
		// 如果不存在key
		if (!bladeRedis.exists(key)){
			bladeRedis.setEx(key, UUID.randomUUID().toString(), Duration.ofSeconds(20L));
			String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"工单编号");
			String finalResult = "维修触发记录" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
			feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
			// 执行完毕后，移除key
			bladeRedis.del(key);
		}else{
			// 等待直到key失效
			try {
				Thread.sleep(20000);
				String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"工单编号");
				String finalResult = "维修触发记录" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
				feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
		}

	}

	/**
	 * 刷新副本维修数据
	 */
	@Override
	public void flushRepairLarkFlushCopy() {
		// 1. 数据准备,  主表appToken, tableId； 两张关联表的appToken，tableId 同步对象
		String appToken = FeiShuDocumentEnum.ELEVATOR_QUEUE_COPY.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_QUEUE_COPY.getTableId();
		String elevatorTableAppToken = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO_COPY.getAppToken();
		String elevatorTableId = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO_COPY.getTableId();
		String userTableAppToken = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO_COPY.getAppToken();
		String userTableId = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO_COPY.getTableId();
		List<LarkRepairVO> targetList = maintainPlanContentService.getLarkRepairVOListByPlanId(null);
		if(Func.isEmpty(targetList)){
			return;
		}
		// 数据处理
		targetList.forEach(t -> {
			// 15、60 天重复故障次数
			// 15 天时间区间
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, -15);
			Date fifteenDaysBeginTime = calendar.getTime();
			Date fifteenDaysEndTime = new Date();
			// 60 天时间区间
			calendar.add(Calendar.DAY_OF_MONTH, -60);
			Date sixtyDaysBeginTime = calendar.getTime();
			Date sixtyDaysEndTime = new Date();
			// 15 天重复故障次数
			int fifteenDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), fifteenDaysBeginTime, fifteenDaysEndTime
			);
			// 60 天重复故障次数
			int sixtyDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), sixtyDaysBeginTime, sixtyDaysEndTime
			);
			t.setFifteenDayRepeatTimes(fifteenDaysRepeatCount);
			t.setSixtyDayRepeatTimes(sixtyDaysRepeatCount);
			t.setIsRepeat(fifteenDaysRepeatCount > 1 || sixtyDaysRepeatCount > 2);
			// 工单完成时间、工单是否已完成
			MaintainPlanContent currentPlan = maintainPlanContentService.getById(t.getPlanId());
			if (!Func.isNull(currentPlan)){
				int statusValue = MaintainPlanContentEnum.MAINTAIN_WX.getId();
				if(new Integer(statusValue).equals(currentPlan.getStatus())){
					t.setFinishTime(currentPlan.getUpdateTime());
					t.setIsFinish(true);
				}
			}
			// 执行人列表
			Long currentPlanId = currentPlan.getId();
			//  2024-06-12 修复改为：包括已删除的执行人列表，取时间最小值
			List<MaintainPlanContentUser> executorList = maintainPlanContentUserService.listAllContentUsersByPlanId(currentPlanId);
			if(!Func.isEmpty(executorList)){
				t.setDispatchTime(executorList.get(0).getCreateTime());
				t.setExecutorIds(
					executorList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList())
				);
			}
			if(!Func.isEmpty(executorList)){
				t.setDispatchTime(executorList.get(0).getCreateTime());
				t.setExecutorIds(
					executorList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList())
				);
			}
			// 工单作业时长分钟
			MaintainPlanContentExt workMinutes = maintainPlanContentExtService.getOne(new LambdaQueryWrapper<MaintainPlanContentExt>()
				.eq(MaintainPlanContentExt::getPlanId, currentPlanId)
				.eq(BaseEntity::getIsDeleted, 0)
			);
			if(!Func.isNull(workMinutes)){
				t.setWorkTime(workMinutes.getWorkMinute());
			}
		});
		// 2. 电梯信息表关联处理
		Map<String, String> elevatorMap = new HashMap<>(100);
		List<JSONObject> elevatorJsonObjects = feiShuDocumentService.commandQueryBatch(elevatorTableAppToken, elevatorTableId, null);
		if(Func.isNotEmpty(elevatorJsonObjects)){
			elevatorJsonObjects.forEach(
				e -> {
					JSONObject elevatorFields = e.getJSONObject("fields");
					String elevatorNum = elevatorFields.getString("电梯编号");
					if(!Func.isNull(elevatorNum)){
						elevatorMap.put(elevatorNum, e.getString("record_id"));
					}
				}
			);
		}
		// 3. 人员信息表关联处理
		Map<String, String> userMap = new HashMap<>(100);
		List<JSONObject> userJsonObjects = feiShuDocumentService.commandQueryBatch(userTableAppToken, userTableId, null);
		if(Func.isNotEmpty(userJsonObjects)){
			userJsonObjects.forEach(
				u -> {
					JSONObject userFields = u.getJSONObject("fields");
					String userId = userFields.getString("人员ID");
					if(!Func.isNull(userId)){
						userMap.put(userId, u.getString("record_id"));
					}
				}
			);
		}
		// 4. 数据封装，先插入没有关联的记录，再插入有关联的记录
		FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
		List<FeiShuFieldsDTO> records = new ArrayList<>();
		for (LarkRepairVO larkRepairVO : targetList) {
			FeiShuFieldsDTO element = new FeiShuFieldsDTO();
			Map<String, Object> elementMap = new HashMap<>(24);
			elementMap.put("工单编号", String.valueOf(larkRepairVO.getPlanId()));
			if(elevatorMap.containsKey(String.valueOf(larkRepairVO.getElevatorId()))){
				List<String> relationIds = new ArrayList<>();
				relationIds.add(elevatorMap.get(String.valueOf(larkRepairVO.getElevatorId())));
				elementMap.put("电梯编号", relationIds.toArray(new String[0]));
			}
			if(Func.isNotEmpty(larkRepairVO.getExecutorIds())){
				List<String> executorIds = new ArrayList<>();
				larkRepairVO.getExecutorIds().forEach(
					e -> {
						if(userMap.containsKey(String.valueOf(e))){
							executorIds.add(userMap.get(String.valueOf(e)));
						}
					});
				if(!Func.isEmpty(executorIds)){
					elementMap.put("人员ID", executorIds.toArray(new String[0]));
				}
			}
			elementMap.put("电梯位置（梯号）", larkRepairVO.getElevatorAddress());
			elementMap.put("报障人", larkRepairVO.getReporterName());
			elementMap.put("报障人联系方式",larkRepairVO.getReporterPhone());
			Integer planFromType = larkRepairVO.getPlanFromType();
			// 任务来源: 1: 物业端, 2: 微信, 3: 服务电话, 4: 系统派单, 5: 维保端，6: 游客, 7: web, 8: 梯联网
			// Switch 语句
			if(!Func.isNull(planFromType)){
				String planFromDesc = "";
				switch (planFromType) {
					case 1:
						planFromDesc = "物业端";
						break;
					case 2:
						planFromDesc = "微信";
						break;
					case 3:
						planFromDesc = "服务电话";
						break;
					case 4:
						planFromDesc = "系统派单";
						break;
					case 5:
						planFromDesc = "维保端";
						break;
					case 6:
						planFromDesc = "游客";
						break;
					case 7:
						planFromDesc = "web";
						break;
					case 8:
						planFromDesc = "梯联网";
						break;
					default:
						planFromDesc = "该工单梯无忧未记录来源";
						break;
				}
				elementMap.put("故障来源", planFromDesc);
			}
			if(!Func.isNull(larkRepairVO.getPlanDesc())){
				List<String> planDescList = Arrays.asList(larkRepairVO.getPlanDesc().split(","));
				List<String> planDescListNew = new ArrayList<>();
				planDescList.forEach(
					p ->{
						Dict dictValue = dictService.getOne(Wrappers.<Dict>lambdaQuery()
							.eq(Dict::getCode, "fault_problem")
							.eq(Dict::getDictKey, p)
							.eq(Dict::getIsDeleted,0)
						);
						if(!Func.isNull(dictValue)){
							planDescListNew.add(dictValue.getDictValue());
						}
					}
				);
				elementMap.put("故障现象",planDescListNew.toArray(new String[0]));
			}
			elementMap.put("故障描述",larkRepairVO.getRepairDesc());
			elementMap.put("电梯状态",new Integer(1).equals(larkRepairVO.getIsStop()) ? "正常" : "停梯");
			Elevator currentElevator = elevatorService.getById(larkRepairVO.getElevatorId());
			Long currentBuildingId = currentElevator.getBuildingId();
			int count = elevatorService.count(new LambdaQueryWrapper<Elevator>()
				.eq(Elevator::getBuildingId, currentBuildingId)
				.eq(TenantEntity::getTenantId,592800)
				.eq(Elevator::getIsDeleted, 0)
			);
			elementMap.put("是否多台梯",count);
			elementMap.put("15天重复故障次数",larkRepairVO.getFifteenDayRepeatTimes());
			elementMap.put("60天重复故障次数",larkRepairVO.getSixtyDayRepeatTimes());
			elementMap.put("是否重复故障",larkRepairVO.getIsRepeat() ? "是" : "否");
			elementMap.put("项目名称",larkRepairVO.getBuildingName());
			elementMap.put("是否驻点",new Integer(1).equals(larkRepairVO.getStagnationPoint()) ? "不限" : "驻点");
			elementMap.put("项目类型", larkRepairVO.getBuildingType());
			if(!Func.isNull(larkRepairVO.getPlanCreateTime())){
				elementMap.put("工单创建时间", larkRepairVO.getPlanCreateTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getFinishTime())){
				elementMap.put("工单完成时间", larkRepairVO.getFinishTime().getTime());
				elementMap.put("工单是否已完成", "是");
			}else {
				elementMap.put("工单是否已完成", "否");
			}
			elementMap.put("创建人", larkRepairVO.getCreateUserName());
			// 签到时间
			if(!Func.isNull(larkRepairVO.getSignTime())){
				elementMap.put("工单签到时间", larkRepairVO.getSignTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getSignOutTime())){
				elementMap.put("工单签退时间", larkRepairVO.getSignOutTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getWorkTime())){
				elementMap.put("工单作业耗时", new Integer(larkRepairVO.getWorkTime()));
			}
			element.setFields(elementMap);
			records.add(element);
		}
		batchDTO.setRecords(records);
		// 5. 执行并发送消息
		String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"工单编号");
		String finalResult = "维修触发记录" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
		feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
	}

	/**
	 * 刷新正本维修数据
	 */
	@Override
	public void flushRepairLarkFlush() {
//		 1. 数据准备,  主表appToken, tableId； 两张关联表的appToken，tableId 同步对象
		String appToken = FeiShuDocumentEnum.ELEVATOR_QUEUE.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_QUEUE.getTableId();
		String elevatorTableAppToken = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO.getAppToken();
		String elevatorTableId = FeiShuDocumentEnum.ELEVATOR_BASIC_INFO.getTableId();
		String userTableAppToken = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO.getAppToken();
		String userTableId = FeiShuDocumentEnum.ELEVATOR_PERSON_INFO.getTableId();
		List<LarkRepairVO> targetList = maintainPlanContentService.getLarkRepairVOListByPlanId(null);
		if(Func.isEmpty(targetList)){
			return;
		}
		// 数据处理
		targetList.forEach(t -> {
			// 15、60 天重复故障次数
			// 15 天时间区间
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, -15);
			Date fifteenDaysBeginTime = calendar.getTime();
			Date fifteenDaysEndTime = new Date();
			// 60 天时间区间
			calendar.add(Calendar.DAY_OF_MONTH, -60);
			Date sixtyDaysBeginTime = calendar.getTime();
			Date sixtyDaysEndTime = new Date();
			// 15 天重复故障次数
			int fifteenDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), fifteenDaysBeginTime, fifteenDaysEndTime
			);
			// 60 天重复故障次数
			int sixtyDaysRepeatCount = maintainPlanContentService.troubleCount(
				t.getElevatorId(), sixtyDaysBeginTime, sixtyDaysEndTime
			);
			t.setFifteenDayRepeatTimes(fifteenDaysRepeatCount);
			t.setSixtyDayRepeatTimes(sixtyDaysRepeatCount);
			t.setIsRepeat(fifteenDaysRepeatCount > 1 || sixtyDaysRepeatCount > 2);
			// 工单完成时间、工单是否已完成
			MaintainPlanContent currentPlan = maintainPlanContentService.getById(t.getPlanId());
			if (!Func.isNull(currentPlan)){
				int statusValue = MaintainPlanContentEnum.MAINTAIN_WX.getId();
				if(new Integer(statusValue).equals(currentPlan.getStatus())){
					t.setFinishTime(currentPlan.getUpdateTime());
					t.setIsFinish(true);
				}
			}
			// 执行人列表
			Long currentPlanId = currentPlan.getId();
			List<MaintainPlanContentUser> executorList = maintainPlanContentUserService.list(
				new LambdaQueryWrapper<MaintainPlanContentUser>()
					.eq(MaintainPlanContentUser::getPlanId, currentPlanId)
					.eq(BaseEntity::getIsDeleted, 0)
					.orderByAsc(BaseEntity::getCreateTime)
			);
			if(!Func.isEmpty(executorList)){
				t.setDispatchTime(executorList.get(0).getCreateTime());
				t.setExecutorIds(
					executorList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList())
				);
			}
			// 工单作业时长分钟
			MaintainPlanContentExt workMinutes = maintainPlanContentExtService.getOne(new LambdaQueryWrapper<MaintainPlanContentExt>()
				.eq(MaintainPlanContentExt::getPlanId, currentPlanId)
				.eq(BaseEntity::getIsDeleted, 0)
			);
			if(!Func.isNull(workMinutes)){
				t.setWorkTime(workMinutes.getWorkMinute());
			}
		});
		// 2. 电梯信息表关联处理
		Map<String, String> elevatorMap = new HashMap<>(100);
		List<JSONObject> elevatorJsonObjects = feiShuDocumentService.commandQueryBatch(elevatorTableAppToken, elevatorTableId, null);
		if(Func.isNotEmpty(elevatorJsonObjects)){
			elevatorJsonObjects.forEach(
				e -> {
					JSONObject elevatorFields = e.getJSONObject("fields");
					String elevatorNum = elevatorFields.getString("电梯编号");
					if(!Func.isNull(elevatorNum)){
						elevatorMap.put(elevatorNum, e.getString("record_id"));
					}
				}
			);
		}
		// 3. 人员信息表关联处理
		Map<String, String> userMap = new HashMap<>(100);
		List<JSONObject> userJsonObjects = feiShuDocumentService.commandQueryBatch(userTableAppToken, userTableId, null);
		if(Func.isNotEmpty(userJsonObjects)){
			userJsonObjects.forEach(
				u -> {
					JSONObject userFields = u.getJSONObject("fields");
					String userId = userFields.getString("人员ID");
					if(!Func.isNull(userId)){
						userMap.put(userId, u.getString("record_id"));
					}
				}
			);
		}
		// 4. 数据封装，先插入没有关联的记录，再插入有关联的记录
		FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
		List<FeiShuFieldsDTO> records = new ArrayList<>();
		for (LarkRepairVO larkRepairVO : targetList) {
			FeiShuFieldsDTO element = new FeiShuFieldsDTO();
			Map<String, Object> elementMap = new HashMap<>(24);
			elementMap.put("工单编号", String.valueOf(larkRepairVO.getPlanId()));
			if(elevatorMap.containsKey(String.valueOf(larkRepairVO.getElevatorId()))){
				List<String> relationIds = new ArrayList<>();
				relationIds.add(elevatorMap.get(String.valueOf(larkRepairVO.getElevatorId())));
				elementMap.put("电梯编号", relationIds.toArray(new String[0]));
			}
			if(Func.isNotEmpty(larkRepairVO.getExecutorIds())){
				List<String> executorIds = new ArrayList<>();
				larkRepairVO.getExecutorIds().forEach(
					e -> {
						if(userMap.containsKey(String.valueOf(e))){
							executorIds.add(userMap.get(String.valueOf(e)));
						}
					});
				if(!Func.isEmpty(executorIds)){
					elementMap.put("人员ID", executorIds.toArray(new String[0]));
				}
			}
			elementMap.put("电梯位置（梯号）", larkRepairVO.getElevatorAddress());
			elementMap.put("报障人", larkRepairVO.getReporterName());
			elementMap.put("报障人联系方式",larkRepairVO.getReporterPhone());
			Integer planFromType = larkRepairVO.getPlanFromType();
			// 任务来源: 1: 物业端, 2: 微信, 3: 服务电话, 4: 系统派单, 5: 维保端，6: 游客, 7: web, 8: 梯联网
			// Switch 语句
			if(!Func.isNull(planFromType)){
				String planFromDesc = "";
				switch (planFromType) {
					case 1:
						planFromDesc = "物业端";
						break;
					case 2:
						planFromDesc = "微信";
						break;
					case 3:
						planFromDesc = "服务电话";
						break;
					case 4:
						planFromDesc = "系统派单";
						break;
					case 5:
						planFromDesc = "维保端";
						break;
					case 6:
						planFromDesc = "游客";
						break;
					case 7:
						planFromDesc = "web";
						break;
					case 8:
						planFromDesc = "梯联网";
						break;
					default:
						planFromDesc = "该工单梯无忧未记录来源";
						break;
				}
				elementMap.put("故障来源", planFromDesc);
			}
			if(!Func.isNull(larkRepairVO.getPlanDesc())){
				List<String> planDescList = Arrays.asList(larkRepairVO.getPlanDesc().split(","));
				List<String> planDescListNew = new ArrayList<>();
				planDescList.forEach(
					p ->{
						Dict dictValue = dictService.getOne(Wrappers.<Dict>lambdaQuery()
							.eq(Dict::getCode, "fault_problem")
							.eq(Dict::getDictKey, p)
							.eq(Dict::getIsDeleted,0)
						);
						if(!Func.isNull(dictValue)){
							planDescListNew.add(dictValue.getDictValue());
						}
					}
				);
				elementMap.put("故障现象",planDescListNew.toArray(new String[0]));
			}
			elementMap.put("故障描述",larkRepairVO.getRepairDesc());
			elementMap.put("电梯状态",new Integer(1).equals(larkRepairVO.getIsStop()) ? "正常" : "停梯");
			Elevator currentElevator = elevatorService.getById(larkRepairVO.getElevatorId());
			Long currentBuildingId = currentElevator.getBuildingId();
			int count = elevatorService.count(new LambdaQueryWrapper<Elevator>()
				.eq(Elevator::getBuildingId, currentBuildingId)
				.eq(TenantEntity::getTenantId,592800)
				.eq(Elevator::getIsDeleted, 0)
			);
			elementMap.put("是否多台梯",count);
			elementMap.put("15天重复故障次数",larkRepairVO.getFifteenDayRepeatTimes());
			elementMap.put("60天重复故障次数",larkRepairVO.getSixtyDayRepeatTimes());
			elementMap.put("是否重复故障",larkRepairVO.getIsRepeat() ? "是" : "否");
			elementMap.put("项目名称",larkRepairVO.getBuildingName());
			elementMap.put("是否驻点",new Integer(1).equals(larkRepairVO.getStagnationPoint()) ? "不限" : "驻点");
			elementMap.put("项目类型", larkRepairVO.getBuildingType());
			if(!Func.isNull(larkRepairVO.getPlanCreateTime())){
				elementMap.put("工单创建时间", larkRepairVO.getPlanCreateTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getFinishTime())){
				elementMap.put("工单完成时间", larkRepairVO.getFinishTime().getTime());
				elementMap.put("工单是否已完成", "是");
			}else {
				elementMap.put("工单是否已完成", "否");
			}
			elementMap.put("创建人", larkRepairVO.getCreateUserName());
			// 签到时间
			if(!Func.isNull(larkRepairVO.getSignTime())){
				elementMap.put("工单签到时间", larkRepairVO.getSignTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getSignOutTime())){
				elementMap.put("工单签退时间", larkRepairVO.getSignOutTime().getTime());
			}
			if(!Func.isNull(larkRepairVO.getWorkTime())){
				elementMap.put("工单作业耗时", new Integer(larkRepairVO.getWorkTime()));
			}
			element.setFields(elementMap);
			records.add(element);
		}
		batchDTO.setRecords(records);
		// 5. 执行并发送消息
		String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"工单编号");
		String finalResult = "维修触发记录" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
		feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
	}

	/**
	 * 临时方法，去重，同步
	 */
	@Override
	@Async
	public void sendPlanScoreLarkMessageTempFull() {
		String activeProfile = System.getProperty("spring.profiles.active");

		// 1. 数据准备，appToken, tableId, 同步对象
		// 复用分页逻辑获取列表，再从中获取单个planId对应的记录，并组装成同步对象
		PlanSearchDTO planSearchDTO = new PlanSearchDTO();
		List<PlanListVo> planListVos = maintainPlanContentService.planListNewLarkTemp(planSearchDTO);
		if(Func.isNotEmpty(planListVos)){
			String appToken;
			String tableId;
			if ("prod".equals(activeProfile)) {
				appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA.getAppToken();
				tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA.getTableId();
			}else{
				appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA_COPY.getAppToken();
				tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_QUALITY_DATA_COPY.getTableId();
			}
			feiShuDocumentService.commandDistinctByKeyAndUpdateTime(appToken, tableId, "梯无忧_保养工单任务ID","评分时间");
			// 2. 数据处理、数据封装
			FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
			List<FeiShuFieldsDTO> records = new ArrayList<>();
			for (PlanListVo planListVo : planListVos) {
				FeiShuFieldsDTO element = new FeiShuFieldsDTO();
				Map<String, Object> elementMap = new HashMap<>(24);
				elementMap.put("梯无忧_保养工单任务ID", String.valueOf(planListVo.getPlanId()));
				elementMap.put("梯无忧_电梯快速识别码", planListVo.getElevatorNum());
				String templateNames = planListVo.getTemplateNames();
				// 1747154112313532417-天雄测试模板,1763081415090966530-天雄保养模板,3-半年保养,4-年度保养
				// 只获取 - 与 , 之间的字符串
				if(!Func.isNull(templateNames)){
					String[] templateNamesArray = templateNames.split(",");
					List<String> templateNameList = new ArrayList<>();
					for (String templateName : templateNamesArray) {
						String[] templateNameArray = templateName.split("-");
						if (templateNameArray.length > 1) {
							templateNameList.add(templateNameArray[1]);
						}
					}
					elementMap.put("任务描述", templateNameList.toArray(new String[0]));
				}
				elementMap.put("项目名称", planListVo.getBuildingName());
				elementMap.put("电梯位置", planListVo.getElevatorAddress());
				if(!Func.isNull(planListVo.getRealNames())){
					String[] realNamesArray = planListVo.getRealNames().split(",");
					elementMap.put("计划执行人", realNamesArray);
				}
				if(!Func.isNull(planListVo.getPlanDate())){
					String planDateString = planListVo.getPlanDate();
					// yyyy-MM-dd 的字符串格式化成 Date
					Date planDate = DateUtil.parse(planDateString, "yyyy-MM-dd");
					elementMap.put("当前计划时间", planDate.getTime());
				}
				// 实际执行人
				List<PlanSignStatusVo> planSignStatusList = planListVo.getPlanSignStatusList();
				List<String> actualExecuteList = new ArrayList<>();
				if(!Func.isEmpty(planSignStatusList)){
					planSignStatusList.stream().map(PlanSignStatusVo::getUserName).forEach(actualExecuteList::add);
					elementMap.put("实际执行人", actualExecuteList.toArray(new String[0]));
				}
				if(!Func.isNull(planListVo.getPlanStartTime())){
					String planStartTimeString = planListVo.getPlanStartTime();
					Date planStartTime = DateUtil.parse(planStartTimeString, "yyyy-MM-dd HH:mm:ss");
					elementMap.put("开始时间", planStartTime.getTime());
				}
				if(!Func.isNull(planListVo.getPlanEndTime())){
					String planEndTimeString = planListVo.getPlanEndTime();
					Date planEndTime = DateUtil.parse(planEndTimeString, "yyyy-MM-dd HH:mm:ss");
					elementMap.put("完成时间", planEndTime.getTime());
				}
				// 有效判定
				if(!Func.isNull(planListVo.getScoreType())){
					if (planListVo.getScoreType() == 1) {
						elementMap.put("有效判定", "有效工单");
					} else if (planListVo.getScoreType() == 2) {
						elementMap.put("有效判定", "无效工单");
					} else if (planListVo.getScoreType() == 3) {
						elementMap.put("有效判定", "无法判断");
					}
				}
				// 工单评分
				if(!Func.isNull(planListVo.getScore())){
					elementMap.put("工单评分", String.valueOf(planListVo.getScore()));
				}
				// 评分时间
				MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(
					new LambdaQueryWrapper<MaintainPlanContentExt>()
						.eq(MaintainPlanContentExt::getPlanId, planListVo.getPlanId())
						.eq(BaseEntity::getIsDeleted, 0)
				);
				// 评分人
				List<PlanCheckHistoryScore> scoreUsers = planCheckHistoryScoreService.list(new LambdaQueryWrapper<PlanCheckHistoryScore>()
					.eq(PlanCheckHistoryScore::getPlanId, planListVo.getPlanId())
					.eq(BaseEntity::getIsDeleted, 0)
				);
				if(!Func.isEmpty(scoreUsers)){
					List<String> collect = scoreUsers.stream().map(PlanCheckHistoryScore::getScoreUserName).collect(Collectors.toList());
					if(!Func.isEmpty(collect)){
						elementMap.put("评分人", collect.toArray(new String[0]));
					}
				}else{
					String scoreUserName = maintainPlanContentExt.getScoreUserName();
					if(!Func.isNull(scoreUserName)){
						List<String> scoreUserNameList = new ArrayList<>();
						scoreUserNameList.add(scoreUserName);
						elementMap.put("评分人", scoreUserNameList.toArray(new String[0]));
					}
				}
				if(!Func.isEmpty(scoreUsers)){
					List<String> collect = scoreUsers.stream().map(PlanCheckHistoryScore::getScoreUserName).collect(Collectors.toList());
					if(!Func.isEmpty(collect)){
						elementMap.put("评分人", collect.toArray(new String[0]));
					}
				}

				if(!Func.isNull(maintainPlanContentExt)){
					Date scoreTime = maintainPlanContentExt.getScoreDate();
					if(!Func.isNull(scoreTime)){
						elementMap.put("评分时间", scoreTime.getTime());
					}
					// 工单总分备注
					if(!Func.isNull(maintainPlanContentExt.getScoreRemark())){
						elementMap.put("工单总分备注", maintainPlanContentExt.getScoreRemark().split(","));
					}
					// 评分状态
					Integer scoreStatus = maintainPlanContentExt.getScoreStatus();
					if(!Func.isNull(scoreStatus)){
						elementMap.put("评分状态", new Integer(1).equals(scoreStatus) ? "已评分" : "未评分");
					}
					// 工单整体评价标签
					if(!Func.isNull(maintainPlanContentExt.getScoreFutilityDesc())){
						String[] split = maintainPlanContentExt.getScoreFutilityDesc().split(",");
						elementMap.put("工单整体评价标签",split);
					}
				}
				// 任务状态
				MaintainPlanContent currentPlan = maintainPlanContentService.getById(planListVo.getPlanId());
				Integer status = currentPlan.getStatus();
				if(!Func.isNull(status)){
					String taskName = TaskStatusEnum.getTaskName(1, status);
					elementMap.put("任务状态", taskName);
				}
				element.setFields(elementMap);
				records.add(element);
			}
			batchDTO.setRecords(records);
			// 3. 执行并发送消息
			String result = feiShuDocumentService.commandCompareAddBatch(appToken,tableId,batchDTO,"梯无忧_保养工单任务ID");
			String finalResult = "工单评分补偿" + FeiShuDocumentEnum.getDescription(appToken,tableId) + result;
			feiShuDocumentService.commandSendGroupMessage(appToken,tableId,finalResult);
		}
	}

}
